<template>
  <div class="menu_box">
    <div class="menu_title">菜单管理</div>
    <!-- 搜索区域 -->
    <div class="menu_search">
      <div class="search_box">
        <el-input v-model="nameSearch" class="name_search input" placeholder="请输入菜单名称"/>
      </div>
      <div class="search_slect">
        <el-select v-model="selectedType" clearable placeholder="请选择菜单类型" style="width: 240px">
          <el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" />
        </el-select>
      </div>
      <div class="add_box">
        <el-button color="#0052CC" @click="openModal('add')">新增</el-button>
      </div>
    </div>

    <!-- 表格 -->
    <el-table 
      :data="pagedTopData" 
      style="width: 100%; margin-bottom: 20px" 
      row-key="id" 
      border 
      :tree-props="{ children: 'children' }"
      :default-expand-all="false"
      :expand-row-keys="expandRowKeys"
    >
      <el-table-column label="序号" width="70" align="center">
        <template #default="data" >
          {{ (currentPage - 1) * pageSize + data.$index + 1 }}
        </template>
      </el-table-column>
      <el-table-column label="页面标题" align="center">
        <template #default="data">
          <div class="title-with-expand">
            <!-- 只有有子节点的行才显示展开/折叠图标 -->
            <span 
              class="expand-icon" 
              v-if="data.row.children && data.row.children.length"
              @click.stop="toggleExpand(data.row.id)"
            >
              <el-icon v-if="isExpanded(data.row.id)">
                <ArrowDown />
              </el-icon>
              <el-icon v-else>
                <ArrowRight />
              </el-icon>
            </span>
            {{ data.row.title }}
          </div>
        </template>
      </el-table-column>
      <el-table-column label="路径" align="center">
        <template #default="data">
          {{ data.row.path }}
        </template>
      </el-table-column>
      <el-table-column label="图标" align="center">
        <template #default="data">
          {{ data.row.icon || '-' }}
        </template>
      </el-table-column>
      <el-table-column label="类型" align="center">
        <template #default="data">
            {{ data.row.type === 1 ? '菜单' : '功能' }}
        </template>
      </el-table-column>
      <el-table-column label="排序" align="center">
        <template #default="data">
          {{ data.row.sort }}
        </template>
      </el-table-column>
      <el-table-column label="操作" align="center">
        <template #default="scope">
          <el-button type="primary" size="small" style="margin-right: 5px" @click="openModal('edit', scope.row)">编辑</el-button>
          <el-button type="danger" size="small" @click="handleDelete(scope.row.id)">删除</el-button>
        </template>
      </el-table-column>
    </el-table>
    
    <!-- 分页 -->
    <div class="pagination-container">
      <el-pagination 
        background 
        layout="total, sizes, prev, pager, next, jumper" 
        :total="filteredTopData.length"
        :page-size="pageSize"
        :page-sizes="[10, 20, 50, 100]"
        :current-page="currentPage"
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
      />
    </div>

    <!-- 新增/编辑弹窗 -->
    <el-dialog 
      v-model="dialogVisible" 
      :title="dialogTitle" 
      width="600px"
      :before-close="handleClose"
    >
      <el-form 
        :model="formData" 
        ref="menuFormRef"
        :rules="formRules"
        label-width="120px"
        size="default"
      >
        <el-form-item label="上级菜单" prop="pid">
          <el-tree-select
            v-model="formData.pid"
            :data="treeSelectData"
            check-strictly
            :render-after-expand="false"
            style="width: 100%"
            placeholder="请选择上级菜单"
            clearable
          />
        </el-form-item>
        
        <el-form-item label="菜单标题" prop="title">
          <el-input v-model="formData.title" placeholder="请输入菜单标题" />
        </el-form-item>
        
        <el-form-item label="菜单路径" prop="path">
          <el-input v-model="formData.path" placeholder="请输入菜单路径" />
        </el-form-item>
        
        <el-form-item label="菜单图标" prop="icon">
          <el-input 
            v-model="formData.icon" 
            placeholder="请输入图标组件名（如：Home）" 
          />
        </el-form-item>
        
        <el-form-item label="菜单类型" prop="type">
          <el-radio-group v-model="formData.type">
            <el-radio :label="1">菜单</el-radio>
            <el-radio :label="2">功能</el-radio>
          </el-radio-group>
        </el-form-item>
        
        <el-form-item label="菜单排序" prop="sort">
          <el-input-number 
            v-model="formData.sort" 
            :min="0" 
            controls-position="right" 
            placeholder="请输入排序号"
          />
        </el-form-item>
      </el-form>
      
      <template #footer>
        <el-button @click="dialogVisible = false">取消</el-button>
        <el-button type="primary" @click="submitForm">确定</el-button>
      </template>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, onMounted, watch, nextTick } from 'vue';
import { getMenuList, addMenu, deleteMenu } from '../../api/account/index.js';
import { ElMessage, ElMessageBox, ElLoading } from 'element-plus';
import { ArrowDown, ArrowRight, Warning } from '@element-plus/icons-vue';
import * as Icons from '@element-plus/icons-vue';

// 定义菜单数据结构接口
interface MenuItem {
  id: string | number;
  title: string;
  path: string;
  icon?: string;
  type: number; // 1: 菜单, 2: 功能
  sort: number;
  pid: string | number; // 父级ID，0表示根节点
  children?: MenuItem[];
  [key: string]: any;
}

// 定义树选择器数据结构接口
interface TreeSelectItem {
  value: string | number;
  label: string;
  children?: TreeSelectItem[];
}

// 分页相关参数
const currentPage = ref(1);
const pageSize = ref(10);

// 搜索相关
const selectedType = ref(''); // 类型筛选
const nameSearch = ref(''); // 名称搜索

// 数据相关
const allData = ref<MenuItem[]>([]); // 完整的树形结构数据
const allFlatData = ref<MenuItem[]>([]); // 扁平化的所有数据
const expandRowKeys = ref<(string | number)[]>([]);
// 弹窗相关
const dialogVisible = ref(false);
const dialogType = ref<'add' | 'edit'>('add');
const dialogTitle = computed(() => dialogType.value === 'add' ? '新增菜单' : '编辑菜单');
const menuFormRef = ref();
const currentEditId = ref<string | number>('');

// 表单数据
const formData = ref<Partial<MenuItem>>({
  pid: '0',
  title: '',
  path: '',
  icon: '',
  type: 1,
  sort: 0
});

// 表单验证规则
const formRules = ref({
  title: [
    { required: true, message: '请输入菜单标题', trigger: 'blur' },
    { max: 50, message: '菜单标题不能超过50个字符', trigger: 'blur' }
  ],
  path: [
    { required: true, message: '请输入菜单路径', trigger: 'blur' }
  ],
  type: [
    { required: true, message: '请选择菜单类型', trigger: 'change' }
  ],
  sort: [
    { required: true, message: '请输入排序号', trigger: 'blur' }
  ]
});

// 选项
const options = [
  { value: '1', label: '菜单' },
  { value: '2', label: '功能' },
];

/**
 * 递归函数：将扁平数组转换为树形结构
 */
const buildTree = (list: MenuItem[], parentId: string | number = 0): MenuItem[] => {
  if (!list || list.length === 0) return [];
  
  const children = list.filter(item => item.pid === parentId);
  
  if (children.length === 0) return [];
  
  return children.map(child => {
    const subChildren = buildTree(list, child.id);
    
    if (subChildren.length > 0) {
      return {
        ...child,
        children: subChildren
      };
    }
    
    return child;
  });
};

/**
 * 将菜单数据转换为 el-tree-select 所需的数据格式
 */
const convertToTreeSelectData = (data: MenuItem[]): TreeSelectItem[] => {
  // 获取所有一级菜单（pid为0的菜单）
  const topLevelMenus = data.filter(item => item.pid === '0' || item.pid === 0);
  
  // 构建树选择器数据
  const treeSelectItems: TreeSelectItem[] = [
    {
      value: '0',
      label: '顶级菜单'
    },
    ...topLevelMenus.map(item => {
      const treeItem: TreeSelectItem = {
        value: item.id,
        label: item.title,
      };
      
      // 如果有子菜单，递归构建子菜单结构
      if (item.children && item.children.length > 0) {
        treeItem.children = convertChildrenToTreeSelectData(item.children);
      }
      
      return treeItem;
    })
  ];
  
  return treeSelectItems;
};

// 辅助函数：用于递归转换子菜单数据
const convertChildrenToTreeSelectData = (children: MenuItem[]): TreeSelectItem[] => {
  return children.map(item => {
    const treeItem: TreeSelectItem = {
      value: item.id,
      label: item.title,
    };
    
    // 递归处理更深层的子菜单
    if (item.children && item.children.length > 0) {
      treeItem.children = convertChildrenToTreeSelectData(item.children);
    }
    
    return treeItem;
  });
};

// 树选择器数据
const treeSelectData = computed<TreeSelectItem[]>(() => {
  return convertToTreeSelectData(allData.value);
});

// 获取顶级节点（pid为0）
const topLevelData = computed<MenuItem[]>(() => {
  return allData.value.filter(item => item.pid === '0' || item.pid === 0);
});

// 筛选顶级节点
const filteredTopData = computed<MenuItem[]>(() => {
  return topLevelData.value.filter(item => {
    // 名称筛选
    const nameMatch = nameSearch.value 
      ? item.title?.toLowerCase().includes(nameSearch.value.toLowerCase()) 
      : true;
    
    // 类型筛选
    const typeMatch = selectedType.value 
      ? item.type.toString() === selectedType.value
      : true;
    
    return nameMatch && typeMatch;
  });
});

// 分页后的顶级节点数据
const pagedTopData = computed<MenuItem[]>(() => {
  const start = (currentPage.value - 1) * pageSize.value;
  const end = start + pageSize.value;
  return filteredTopData.value.slice(start, end);
});

// 初始化展开所有节点
const initExpandAll = () => {
  const getAllIds = (items: MenuItem[]): (string | number)[] => {
    let ids: (string | number)[] = [];
    items.forEach(item => {
      ids.push(item.id);
      if (item.children && item.children.length > 0) {
        ids = ids.concat(getAllIds(item.children));
      }
    });
    return ids;
  };
  expandRowKeys.value = getAllIds(allData.value);
};

// 获取菜单列表数据
const fetchMenuList = async () => {
  try {
    const res = await getMenuList();
    // 构建完整的树形结构
    const treeData = buildTree(res.data || []);
    allData.value = treeData;
    
    // 生成扁平化数据用于其他操作
    const flatten = (items: MenuItem[]): MenuItem[] => {
      return items.reduce<MenuItem[]>((acc, item) => {
        acc.push(item);
        if (item.children && item.children.length > 0) {
          acc.push(...flatten(item.children));
        }
        return acc;
      }, []);
    };
    
    allFlatData.value = flatten(treeData);
    
    // 初始化展开状态
    nextTick(() => {
      initExpandAll();
    });
  } catch (error) {
    console.error('获取菜单列表失败:', error);
  }
};

// 打开弹窗
const openModal = (type: 'add' | 'edit', row?: MenuItem) => {
  dialogType.value = type;
  dialogVisible.value = true;
  
  // 重置表单
  if (menuFormRef.value) {
    menuFormRef.value.resetFields();
  }
  
  if (type === 'add') {
    // 新增 - 设置默认值
    formData.value = {
      pid: '0',
      title: '',
      path: '',
      icon: '',
      type: 1,
      sort: 0
    };
  } else if (type === 'edit' && row) {
    // 编辑 - 填充表单数据
    currentEditId.value = row.id;
    formData.value = {
      id: row.id,
      pid: row.pid === 0 || row.pid === '0' ? '0' : row.pid,
      title: row.title,
      path: row.path,
      icon: row.icon || '',
      type: row.type,
      sort: row.sort
    };
  }
};

// 关闭弹窗
const handleClose = () => {
  dialogVisible.value = false;
  currentEditId.value = '';
};

// 提交表单
const submitForm = async () => {
  if (!menuFormRef.value) return;
  
  try {
    // 表单验证
    await menuFormRef.value.validate();
    
    // 显示加载提示
    const loading = ElLoading.service({ text: '提交中...', background: 'rgba(0, 0, 0, 0.7)' });
    
    if (dialogType.value === 'add') {
      // 新增菜单
      await addMenu(formData.value);
      ElMessage.success('新增菜单成功');
    } else {
      // 编辑菜单
      await addMenu(formData.value);
      ElMessage.success('编辑菜单成功');
    }
    
    // 关闭加载提示
    loading.close();
    
    // 关闭弹窗并刷新数据
    dialogVisible.value = false;
    fetchMenuList();
  } catch (error) {
    console.error('提交失败:', error);
    if (error instanceof Error) {
      ElMessage.error(error.message);
    } else {
      ElMessage.error('提交失败，请稍后重试');
    }
  }
};

// 处理删除
const handleDelete = async (id: string | number) => {
  try {
    // 确认删除操作
    await ElMessageBox.confirm(
      '确定要删除该菜单吗？删除后可能会影响相关功能',
      '确认删除',
      {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning',
        icon: Warning,
      }
    );
    
    // 显示加载状态
    const loading = ElLoading.service({ 
      text: '删除中...', 
      background: 'rgba(0, 0, 0, 0.7)' 
    });
    
    try {
      // 检查是否有子菜单
      const hasChildren = allFlatData.value.some(item => item.pid === id);
      if (hasChildren) {
        // 如果有子菜单，提示用户
        const confirm = await ElMessageBox.confirm(
          '该菜单下存在子菜单，删除后子菜单也会一并删除，确定要删除吗？',
          '确认删除',
          {
            confirmButtonText: '确定',
            cancelButtonText: '取消',
            type: 'warning',
            icon: Warning,
          }
        ).catch(() => 'cancel');
        
        if (confirm === 'cancel') {
          return;
        }
      }
      
      // 执行删除操作
      console.log(id);
      await deleteMenu({id:id});
      ElMessage.success('删除成功');
      // 刷新菜单列表
      await fetchMenuList();
    } finally {
      // 无论成功或失败都关闭加载状态
      loading.close();
    }
  } catch (error) {
    // 只有当不是用户取消操作时才显示错误信息
    if (error !== 'cancel' && error !== 'close') {
      console.error('删除失败:', error);
      ElMessage.error('删除失败，请稍后重试');
    }
  }
};

// 处理每页条数变化
const handleSizeChange = (val: number) => {
  pageSize.value = val;
  currentPage.value = 1;
};

// 处理页码变化
const handleCurrentChange = (val: number) => {
  currentPage.value = val;
};

// 切换展开状态
const toggleExpand = (id: string | number) => {
  const idStr = id.toString();
  const index = expandRowKeys.value.indexOf(idStr);
  
  if (index > -1) {
    // 收起当前节点及其所有子节点
    const collectAllChildIds = (parentId: string | number): (string | number)[] => {
      const children = allFlatData.value.filter(item => item.pid === parentId);
      let ids: (string | number)[] = [parentId.toString()];
      children.forEach(child => {
        ids = ids.concat(collectAllChildIds(child.id));
      });
      return ids;
    };
    
    const allIdsToCollapse = collectAllChildIds(id);
    expandRowKeys.value = expandRowKeys.value.filter(
      key => !allIdsToCollapse.includes(key)
    );
  } else {
    // 展开当前节点
    expandRowKeys.value = [...expandRowKeys.value, idStr];
  }
};

const isExpanded = (id: string | number) => {
  return expandRowKeys.value.includes(id.toString());
};

// 监听搜索条件变化
watch([nameSearch, selectedType], () => {
  currentPage.value = 1; // 重置到第一页
});

// 页面加载时获取数据
onMounted(() => {
  fetchMenuList();
});
</script>

<style scoped>
.menu_title {
  background: #fff;
  width: 100%;
  height: 60px;
  font-size: 24px;
  font-weight: 500;
  display: flex;
  align-items: center;
  border-bottom: 1px solid #eee;
  margin-bottom: 15px;
  padding-left: 20px;
}

.menu_search {
  display: flex;
  padding: 0 2%;
  margin-bottom: 15px;
  align-items: center;
  flex-wrap: wrap;
  gap: 15px;
}

.search_box {
  min-width: 240px;
}

.name_search {
  width: 100%;
}

.add_box {
  margin-left: auto;
}

/* 分页容器样式 */
.pagination-container {
  display: flex;
  justify-content: center;
  padding: 0 2%;
  margin-top: 10px;
}

/* 调整表格行高 */
::v-deep .el-table__row {
  height: 50px;
}

/* 表单样式优化 */
::v-deep .el-form-item {
  margin-bottom: 20px;
}

/* 树形下拉选择器样式优化 */
::v-deep .el-select-dropdown__item {
  white-space: nowrap;
}

/* 标题与展开图标样式 */
.title-with-expand {
  display: flex;
  align-items: center;
  gap: 8px;
}

.expand-icon {
  cursor: pointer;
  color: #409eff;
  font-size: 14px;
  width: 16px;
  text-align: center;
  transition: transform 0.3s ease;
}

.expand-icon:hover {
  color: #66b1ff;
}

::v-deep .el-icon {
  vertical-align: middle;
}

/* 隐藏表格默认的展开/折叠图标 */
::v-deep .el-table__expand-icon {
  display: none !important;
}

/* 去除展开列的占位空间 */
::v-deep .el-table__expand-column {
  width: 0 !important;
  padding: 0 !important;
}
</style>